package com.hmall.search.listener;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.hmall.api.client.ItemClient;
import com.hmall.api.dto.ItemDTO;
import com.hmall.search.domain.po.ItemDoc;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.IOException;

@Slf4j
@Component
@RequiredArgsConstructor
public class ItemListener {

    private final RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(
            HttpHost.create("http://192.168.32.139:9200")
    ));

    private final ItemClient itemClient;

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = "search.item.index.queue", durable = "true"),
            exchange = @Exchange(name = "search.direct"),
            key = {"item.index.addOrUpdate"}
    ))
    public void listenItemIndexAddDoc(Long itemId) throws IOException {
        //接受消息，获取商品id，定义ItemDoc对象
        ItemDTO itemDTO = itemClient.queryItemById(itemId);
        ItemDoc itemDoc = BeanUtil.copyProperties(itemDTO, ItemDoc.class);
        //1.准备request
        IndexRequest request = new IndexRequest("items").id(itemDoc.getId());
        //2.设置文档内容
        request.source(JSONUtil.toJsonStr(itemDoc), XContentType.JSON);
        //3.发送请求
        client.index(request, RequestOptions.DEFAULT);
    }

    /**
     * 监听这个的意思是，如果某个商品的状态变为了删除了，那么这里的方法就在索引库中删除，
     * 因为ItemDoc中是没有Status字段的，所以这里不是简单的对status的更改
     * <p>
     * WARNING 监听商品状态，如果商品状态删除了，这里也对商品进行删除，
     * WARNING 但其实，商品状态改为5时，可以直接给listenItemDeleteDoc()来发送信息，发送给谁都一样，反而不用这么写
     */
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = "search.item.status.queue", durable = "true"),
            exchange = @Exchange(name = "search.direct"),
            key = {"item.index.updateStatus"}
    ))
    public void listenItemUpdateStatus(Long id) {
        /*ItemDTO itemDTO = itemClient.queryItemById(id);
        ItemDoc itemDoc = BeanUtil.copyProperties(itemDTO, ItemDoc.class);
        UpdateRequest request = new UpdateRequest("items", itemDoc.getId());
        request.doc(
                "status", itemDoc.
        )*/
    }

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = "search.item.delete.queue", durable = "true"),
            exchange = @Exchange(name = "search.direct"),
            key = {"item.index.delete"}
    ))
    public void listenItemDeleteDoc(Long itemId) throws IOException {
        /**
         * WARNING 这里原先这样写报错，干脆直接不转化直接传id来删除，这样反而不会报错，我也不太理解
         */
       /*
        ItemDTO itemDTO = itemClient.queryItemById(itemId);
        ItemDoc itemDoc = BeanUtil.copyProperties(itemDTO, ItemDoc.class);
        System.out.println("---itemDoc = " + itemDoc);
        */
        DeleteRequest request = new DeleteRequest("items", itemId.toString());
        client.delete(request, RequestOptions.DEFAULT);
    }
}
